<template>
  <el-dialog
    v-model="dialog.visible"
    title="编辑代码模板"
    @open="openHandler"
    @close="closeHandler"
    :close-on-click-modal="false"
    append-to-body
    center
    fullscreen
  >
    <el-form
      ref="dataForm"
      :model="entity"
      :rules="formRules"
      label-position="left"
      label-width="auto"
      label-suffix="："
      class="codeTemplate"
    >
      <el-row :gutter="20">
        <el-col :span="4">
          <el-form-item prop="codeTemplateName" label="模板名称">
            <el-input
              v-model="entity.codeTemplateName"
              placeholder="请输入模板名称"
              clearable
            />
          </el-form-item>
        </el-col>
        <el-col :span="4">
          <el-form-item prop="tableName" label="表名">
            <el-input v-model="entity.tableName" disabled />
          </el-form-item>
        </el-col>
        <el-col :span="4">
          <el-form-item prop="tablePrefix" label="表前缀">
            <el-input
              v-model="entity.tablePrefix"
              placeholder="请输入表前缀"
              @input="
                () => {
                  previewFileName()
                  preview()
                }
              "
            />
          </el-form-item>
        </el-col>

        <el-col :span="4">
          <el-form-item prop="parentPackage" label="包名">
            <el-input
              v-model="entity.parentPackage"
              placeholder="请输入包名"
              @input="
                () => {
                  previewFilePath()
                  preview()
                }
              "
            />
          </el-form-item>
        </el-col>

        <el-col :span="4">
          <el-form-item prop="moduleName" label="模块名">
            <el-input
              v-model="entity.moduleName"
              placeholder="请输入模块名"
              @input="
                () => {
                  previewFilePath()
                  preview()
                }
              "
            />
          </el-form-item>
        </el-col>

        <el-col :span="4">
          <el-form-item prop="author" label="作者">
            <el-input
              v-model="entity.author"
              placeholder="请输入作者"
              @input="preview()"
            />
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="20">
        <el-col :span="6">
          <el-form-item prop="fileName" label="文件名">
            <el-input
              v-model="entity.fileName"
              placeholder="请输入文件名"
              clearable
              @blur="previewFileName"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="真实名">
            <el-input v-model="entity.realFileName" readonly />
          </el-form-item>
        </el-col>

        <el-col :span="6">
          <el-form-item prop="filePath" label="文件路径">
            <el-input
              v-model="entity.filePath"
              placeholder="请输入文件路径"
              clearable
              @blur="previewFilePath"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="filePath" label="真实路径">
            <el-input v-model="entity.realFilePath" readonly />
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item prop="codeTemplateFile" label="模板文件">
            <textarea ref="codeEditor" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="预览效果">
            <textarea ref="previewCodeEditor" />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>

    <env-variable v-model="drawerVisible" />

    <template #footer>
      <el-button size="small" @click="drawerVisible = true">环境变量</el-button>
      <el-button size="small" @click="dialog.visible = false">取 消</el-button>
      <el-button type="primary" size="small" @click="saveHandler">
        保 存
      </el-button>
    </template>
  </el-dialog>
</template>
<script>
import { modify } from '@/api/codegen/codeTemplate'
import { preview, previewFileName, previewFilePath } from '@/api/codegen'
import EnvVariable from './EnvVariable'

import CodeMirror from 'codemirror'

import 'codemirror/lib/codemirror.css'
import 'codemirror/theme/dracula.css' // 配置里面也需要theme设置为monokai
// 编辑的主题文件
import 'codemirror/theme/monokai.css'
import 'codemirror/theme/base16-light.css'

// keyMap
import 'codemirror/mode/clike/clike.js'
import 'codemirror/mode/sql/sql.js'
import 'codemirror/mode/xml/xml.js'
import 'codemirror/mode/javascript/javascript.js'

import 'codemirror/addon/edit/closebrackets.js'
import 'codemirror/addon/selection/active-line'

require('codemirror/addon/fold/foldcode.js')
require('codemirror/addon/fold/foldgutter.js')
require('codemirror/addon/fold/brace-fold.js')
require('codemirror/addon/fold/xml-fold.js')
require('codemirror/addon/fold/indent-fold.js')
require('codemirror/addon/fold/markdown-fold.js')
require('codemirror/addon/fold/comment-fold.js')

import 'codemirror/addon/selection/mark-selection.js'

import 'codemirror/addon/hint/show-hint.js'
import 'codemirror/addon/hint/sql-hint.js'
import 'codemirror/addon/hint/show-hint.css'
import 'codemirror/addon/hint/javascript-hint.js'

import 'codemirror/addon/scroll/annotatescrollbar.js'
import 'codemirror/addon/search/matchesonscrollbar.js'
import 'codemirror/addon/search/match-highlighter.js'

import 'codemirror/addon/edit/matchbrackets.js'
import 'codemirror/addon/comment/comment.js'
import 'codemirror/addon/dialog/dialog.js'
import 'codemirror/addon/dialog/dialog.css'
import 'codemirror/addon/search/searchcursor.js'
import 'codemirror/addon/search/search.js'
import 'codemirror/keymap/sublime.js'

export default {
  name: 'TemplateModify',
  props: {
    dialog: {
      type: Object,
      required: true,
    },
  },
  emits: ['success'],
  data() {
    return {
      entity: {},
      formRules: {
        codeTemplateName: [
          { required: true, message: '请输入模板名称', trigger: 'blur' },
        ],
        codeTemplateFile: [
          { required: true, message: '模板内容不能为空', trigger: 'blur' },
        ],
        parentPackage: [
          { required: true, message: '请输入包名', trigger: 'blur' },
        ],
        moduleName: [
          { required: true, message: '请输入模块名', trigger: 'blur' },
        ],
        author: [{ required: true, message: '请输入作者', trigger: 'blur' }],
        fileName: [
          { required: true, message: '请输入文件名', trigger: 'blur' },
        ],
        filePath: [
          { required: true, message: '请输入文件路径', trigger: 'blur' },
        ],
      },
      cmOptions: {
        mode: 'text/x-java', //Java语言
        smartIndent: true, // 自动缩进
        autoCloseBrackets: true, // 自动补全括号
        tabSize: 4, // tab的空格个数
        theme: 'dracula', //主题样式
        lineNumbers: true, //是否显示行数
        lineWrapping: true, //是否自动换行
        styleActiveLine: true, //line选择是是否加亮
        matchBrackets: true, //括号匹配
        option: {
          autofocus: true,
        },
      },
      codeEditor: null,
      previewCodeEditor: null,
      previewTimeout: null,
      drawerVisible: false,
    }
  },
  components: {
    EnvVariable,
  },
  methods: {
    openHandler() {
      this.entity = Object.assign(
        {
          dataSourceName: 'master',
          codeTemplateFile: '',
          tableName: 'jaguar_codegen_code_template',
          tablePrefix: 'jaguar_codegen_',
          parentPackage: 'top.wilsonlv.jaguar',
          moduleName: 'codegen',
          author: 'lvws',
          fileName: '',
          filePath: '',
          realFileName: '',
          realFilePath: '',
        },
        this.dialog.entity
      )

      this.$nextTick(() => {
        let codeEditor = this.$refs.codeEditor
        codeEditor.value = this.entity.codeTemplateFile

        this.codeEditor = CodeMirror.fromTextArea(
          codeEditor,
          Object.assign({ readOnly: false }, this.cmOptions)
        )

        this.codeEditor.on('change', (coder) => {
          this.entity.codeTemplateFile = coder.getValue()
          this.preview()
        })

        this.preview(true)
        this.previewFileName()
        this.previewFilePath()
      })
    },
    closeHandler() {
      this.entity = {}
      this.codeEditor.toTextArea()
      this.previewCodeEditor.toTextArea()
    },
    previewFileName() {
      if (this.entity.fileName) {
        previewFileName({
          tableName: this.entity.tableName,
          tablePrefix: this.entity.tablePrefix,
          fileName: this.entity.fileName,
        }).then((res) => {
          this.entity.realFileName = res.data.data
        })
      }
    },
    previewFilePath() {
      if (
        this.entity.parentPackage &&
        this.entity.moduleName &&
        this.entity.filePath
      ) {
        previewFilePath({
          tableName: this.entity.tableName,
          tablePrefix: this.entity.tablePrefix,
          parentPackage: this.entity.parentPackage,
          moduleName: this.entity.moduleName,
          filePath: this.entity.filePath,
        }).then((res) => {
          this.entity.realFilePath = res.data.data
        })
      }
    },
    preview(inmediately = false) {
      if (!this.entity.codeTemplateFile) {
        let codeEditor = this.$refs.previewCodeEditor
        codeEditor.value = ''

        this.previewCodeEditor = CodeMirror.fromTextArea(
          this.$refs.previewCodeEditor,
          Object.assign({ readOnly: true }, this.cmOptions)
        )
        return
      }

      let previw = () => {
        preview(this.entity).then((res) => {
          let scrollTop
          if (this.previewCodeEditor) {
            scrollTop = this.previewCodeEditor.display.scroller.scrollTop
            this.previewCodeEditor.toTextArea()
          } else {
            scrollTop = 0
          }

          let codeEditor = this.$refs.previewCodeEditor
          codeEditor.value = res.data.data

          this.previewCodeEditor = CodeMirror.fromTextArea(
            codeEditor,
            Object.assign({ readOnly: true }, this.cmOptions)
          )

          this.previewCodeEditor.display.scroller.scrollTop = scrollTop
          this.previewTimeout = null
        })
      }

      if (inmediately) {
        previw()
      } else {
        if (this.previewTimeout) clearTimeout(this.previewTimeout)
        this.previewTimeout = setTimeout(() => {
          previw()
        }, 1500)
      }
    },
    saveHandler() {
      this.$refs.dataForm.validate((valid) => {
        if (valid) {
          modify(this.entity).then(() => {
            this.dialog.visible = false
            this.$message({
              showClose: true,
              message: '保存成功',
              type: 'success',
            })
            this.$emit('success')
          })
        }
      })
    },
  },
}
</script>
<style lang="scss">
.codeTemplate {
  .CodeMirror {
    height: 640px;

    .CodeMirror-line {
      line-height: 28px;
    }
  }
}
.envVariables {
  .CodeMirror {
    height: 800px;
  }
}
</style>
